import argparse
parser = argparse.ArgumentParser(description='请用管理员权限运行')
parser.add_argument("filename")
args = parser.parse_args()
filename = args.filename
print("文件名: "+filename)

file = open(filename,'r');
flines = file.readlines();
file.close();

# 音乐速度始终在第二行
bpm = int(flines[1].strip('bpm= \n'));
print("bpm: "+str(bpm))

i=0;
while(i!=len(flines)):
    flines[i] = flines[i].rstrip('\n\t ');
    i+=1;


''' 获取文件中的曲谱们，每份曲谱以一个字符串的形式存在music表中。
    一份曲谱介于begin和end中间。
    共有两份曲谱，也就是两个begin end
'''
musics = []; #乐谱列表
i=0;
while(i!=len(flines)):
    if flines[i]=='begin' :
        i+=1;
        tmp='';
        while(flines[i]!='end'):
            tmp += flines[i];
            i+=1;
        else:
            musics.append(tmp);
    i+=1;
#print("曲谱1文本: "+musics[0]);
#print("曲谱2文本: "+musics[1]);

# 字符串str，显示p所在位置前边的5个字符。
def location(str,p):
    if p>=5 & p<=len(str) : return str[p-5:p];
    if p<5 & p<=len(str) : return str[0:p];


#计算一个音符对应的时长（拍子）,p指向该音符
flag = {'-','+','0','1','2','3','4','5','6','7','('};#开始下一个音符统计的标志
def beat(music,p): 
    时长=1;   #默认一拍
    if p+1>=len(music) : 
        return [时长,p+1];
    else:
        p = p+1;
        last_time = 1; #表示上一个字符的拍数，默认1
        while not music[p] in flag :
            if music[p]=='~' : 
                时长=时长+1;               # '~'表示一拍
                last_time = 1;
            if music[p]=='_' : 
                时长=时长*0.5;
                last_time = 时长;          # '_'放最前，可凑x.25    __=0.25  __~=1.25
            if music[p]=='.' : 
                时长=时长+last_time*0.5;
                last_time = last_time*0.5; # '.'放最后，可凑x.75    _.=0.75  _.~=1.75
            p+=1;
            if p==len(music) :
                return [时长,p];
        return [时长,p];

'''
若规定
5~~~ 四拍
5~      二拍
5         一拍
5_       半拍
5__      四分之一拍
5___     八分之一拍

--5       倍低音
-5        低音
5          中音
+5       高音
++5     倍高音

5.       附点音符

()         同时按下

'''
music_lists=[];  #乐谱由字符串转化为列表数据结构存储
for music in musics:
    p=0;低音点=0;高音点=0;
    music_tmp=[];
    while p<len(music) :
        if music[p] in flag :
            if music[p]=='-' : 低音点=低音点-1;p+=1;
            if music[p]=='+' : 高音点=高音点+1;p+=1;
            if music[p] in {'0','1','2','3','4','5','6','7'} :
                音符=(str(低音点+高音点),music[p]); #音符=[音阶,数字]
                音符表=[];                          #音符表=[音符,音符,...]
                音符表.append(音符);
                #开始算该音符表对应的时长
                tmp = [];tmp.append(音符表);
                t = beat(music,p);
                tmp.append(t[0]); 
                music_tmp.append(tmp);#添加[音符表,时长]
                低音点=0;高音点=0;
                p = t[1];
                #print("note: "+str(tmp)+"    p->"+location(music,p));
                if(p>=len(music)): 
                        continue;
            if music[p]=='(' :
                p+=1;
                音符表=[];     
                while music[p]!=')' :
                    if music[p]=='-' : 低音点=低音点-1;p+=1;
                    if music[p]=='+' : 高音点=高音点+1;p+=1;
                    if music[p] in {'0','1','2','3','4','5','6','7'}:
                        音符=(str(低音点+高音点),music[p]);
                        音符表.append(音符);                
                        低音点=0;高音点=0;
                        p=p+1;
                else:
                    tmp = [];
                    tmp.append(音符表);
                    t=beat(music,p)
                    tmp.append(t[0]);
                    p=t[1];
                    if(p>=len(music)): 
                        continue;
                    music_tmp.append(tmp);
    music_lists.append(music_tmp);       

dic = {('1','1'):'q', ('1','2'):'w', ('1','3'):'e', ('1','4'):'r', ('1','5'):'t', ('1','6'):'y', ('1','7'):'u',
       ('0','1'):'a', ('0','2'):'s', ('0','3'):'d', ('0','4'):'f', ('0','5'):'g', ('0','6'):'h', ('0','7'):'j',
       ('-1','1'):'z', ('-1','2'):'x', ('-1','3'):'c', ('-1','4'):'v', ('-1','5'):'b', ('-1','6'):'n', ('-1','7'):'m',
       ('0','0'):' '};

import time;
import keyboard;
#弹一个曲谱的线程
def playmusic(乐谱):
    print("开始播放音乐："+str(id(乐谱)));
    for notes in 乐谱 :
        tmp = [];
        for note in notes[0]:
            tmp.append(dic[note]);
        hotkey = '+'.join(tmp); 
        if hotkey!='' :
            keyboard.press(hotkey);
            keyboard.release(hotkey);
        time.sleep(notes[1]*60/bpm);#停顿时长秒;


import multiprocessing;
if __name__ == "__main__":
    print("5秒后开始:"); 
    for i in range(5):
        print(5-i);
        time.sleep(1);    
    
    lefthand = multiprocessing.Process(target = playmusic, args = (music_lists[0],))
    # 进程二演奏过程中存在延时，请勿使用
    righthand = multiprocessing.Process(target = playmusic, args = (music_lists[1],))
    
    lefthand.start()
    righthand.start()
